<?php
/**
 * Created by PhpStorm.
 * User: 小蛮哼哼哼
 * Email: 243194993@qq.com
 * Date: 2022/5/16
 * Time: 13:54
 * motto: 现在的努力是为了小时候吹过的牛逼！
 */

namespace app\common\lib\printer;

use App\Api\ExpressPrintService;
use App\Api\PicturePrintService;
use App\Api\PrinterService;
use App\Api\PrintService;
use app\common\lib\Show;
use app\common\lib\Status;
use app\common\model\PrinterOrder;
use App\Config\YlyConfig;
use App\Oauth\YlyOauthClient;
use think\facade\Cache;

class Yilian extends Base
{
    protected $config = [];
    protected $token = [];
    protected $cache_key = "";

    /**
     * @param array $config 包含应用id 和应用密钥
     * @param string $code
     * @throws \Exception
     */
    public function __construct(array $config = [], string $code = "")
    {
        $this->cache_key = md5("cache_20220222222222_yiLian");
        //判断是否存在  $clientId, $clientSecret
        if (empty($config['clientId'])) {
            throw new \Exception("应用id不存在");
        }
        if (empty($config['clientSecret'])) {
            throw new \Exception("应用密钥不存在");
        }
        $this->config = new YlyConfig($config['clientId'], $config['clientSecret']);

        //公共获取token
        //获取
        $getCache = Cache::get($this->cache_key);

        if ($getCache) {
            $this->token = Show::json_decode($getCache);
        } else {
            $this->__token($code);
        }
    }

    /**
     * 机器授权
     * @param string $machineCode 机器编号
     * @param string $mSign
     * @param string $printName
     * @param string $phone
     * @return array
     * @throws \Exception
     */
    public function auth(string $machineCode = "", string $mSign = "", string $printName = '', string $phone = ''): array
    {
        //机器授权
        if (empty($machineCode)) {
            throw new \Exception("您的机器码不存在");
        }
        if (empty($mSign)) {
            throw new \Exception("您的机器密钥不存在");
        }
        //授权打印机
        $printer = new PrinterService($this->token['access_token'], $this->config);
        $result = $printer->addPrinter($machineCode, $mSign, $printName, $phone);
        return (array)$result;
    }

    /**
     * @param array $data
     * @return array
     * @throws \Exception
     */
    public function printer(array $data = []): array
    {
        if (empty($data['machineCode'])) {
            throw new \Exception("机器不存在");
        }
        if (empty($data['content'])) {
            throw new \Exception("打印内容不存在");
        }
        if (empty($data['id'])) {
            $data['id'] = $this->guid();
        }
        if (empty($data['timestamp'])) {
            $data['timestamp'] = time();
        }
        //创建订单
        $insert_data = [
            "openid" => $data['openid'],
            "timestamp" => $data['timestamp'],
            "machineCode" => $data['machineCode'],
            "content" => $data['content'],
            "order_id" => $data['id'],
            "type" => $data['type'],
            "create_time" => time(),
            "update_time" => time()
        ];
        $obj_order = new PrinterOrder();
        $res = $obj_order->insertSaveById($insert_data);
        if (!$res) {
            throw new \Exception("服务内部异常");
        }
        if ($data['type'] == 1) {  //文本打印
            $print = new PrintService($this->token['access_token'], $this->config);
            $result = $print->index($data['machineCode'], $data['content'], $data['id']);
        } else if ($data['type'] == 2) {  //图片
            $print = new PicturePrintService($this->token['access_token'], $this->config);
            $result = $print->index($data['machineCode'], $data['content'], $data['id']);
        } else if ($data['type'] == 3) { //面单
            $print = new ExpressPrintService($this->token['access_token'], $this->config);
            $result = $print->index($data['machineCode'], $data['content'], $data['id']);
        }
        $ret = (array)$result;
        if ($ret['error'] == 0) {
            //更新数据
            $obj_order->updateDataSave($res, [
                "status" => 2,
                "update_time" => time(),
                "merchant_id" => $ret['body']->id
            ]);
            return Show::json_show(Status::status_normal, "发送打印成功", [
                "id" => $ret['body']->id,
                "origin_id" => $ret['body']->origin_id
            ], 1, true);
        } else {
            $obj_order->updateDataSave($res, [
                "status" => 3,
                "error_description" => $ret['error_description'],
                "update_time" => time()
            ]);
            return Show::json_show(Status::status_error, $ret['error_description'], [], 1, true);
        }
    }


    /**
     * 获取token
     * @param string $code
     * @return void
     * @throws \Exception
     */
    protected function __token(string $code = "")
    {
        $client = new YlyOauthClient($this->config);

        $token = $client->getToken($code);
        $ret = (array)$token;
        if (empty($ret['access_token'])) {
            //
            throw new \Exception("获取token失败");
        }
        //记录缓存
        $ret = Cache::set($this->cache_key, Show::json_encode($ret));
        if ($ret) {
            $this->token = $ret;
        } else {
            throw new \Exception("获取token失败！请重试");
        }
    }
}